package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AssertUtil;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.VipServiceConfigService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {


    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;
    @Autowired
    private UserVipServiceMapper userVipServiceMapper;
    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @Override
    public UserInfoVo getCurrentUserInfo() {

        Long userId = AuthContextHolder.getUserId();
        UserInfo userInfo = this.getById(userId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }

    @Override
    public void updateUser(UserInfo userInfo) {

        userInfo.setId(AuthContextHolder.getUserId());
        this.updateById(userInfo);
    }

    @Override
    public UserInfoVo getUserInfoById(Long userId) {
        UserInfo userInfo = this.getById(userId);
        if (userInfo != null) {
            UserInfoVo userInfoVo = new UserInfoVo();
            BeanUtils.copyProperties(userInfo, userInfoVo);
            return userInfoVo;
        }
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }

    // 获取用户购买的该专辑下的声音列表
    @Override
    public List<UserPaidTrack> getUserBuyTrackIdList(Long userId, Long albumId) {
        List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(
                new LambdaQueryWrapper<UserPaidTrack>()
                        .eq(UserPaidTrack::getUserId, userId)
                        .eq(UserPaidTrack::getAlbumId, albumId)
        );
        return userPaidTrackList;
    }

    // 远程调用判断用户是否购买过该专辑
    @Override
    public Boolean isBuyAlbum(Long userId, Long albumId) {
        Long count = userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>()
                .eq(UserPaidAlbum::getUserId, userId)
                .eq(UserPaidAlbum::getAlbumId, albumId));
        return count > 0;
    }

    @Override
    public void saveUserPaidRecord(UserPaidRecordVo userPaidRecordVo) {
        // 远程调用user服务 保存交易记录 saveUserPaidRecord
        // 1. 如果是vip
        // 2. 如果是专辑
        // 3， 如果是声音
        switch (userPaidRecordVo.getItemType()) {
            // 1. vip
            case SystemConstant.ORDER_ITEM_TYPE_VIP:
                saveVip(userPaidRecordVo);
                break;
            // 2. 专辑
            case SystemConstant.ORDER_ITEM_TYPE_ALBUM:
                saveAlbum(userPaidRecordVo);
                break;
            // 3. 声音
            case SystemConstant.ORDER_ITEM_TYPE_TRACK:
                saveTracks(userPaidRecordVo);
                break;
        }
    }



    // 抽取方法
    // 1. 提交的是vip
    private void saveVip(UserPaidRecordVo userPaidRecordVo) {


        // 查询用户的vipConfig 得到用户所买的vip的属性
        VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
        if (vipServiceConfig == null) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }

        // 用户此次购买的vip服务时间为
        Integer serviceMonth = vipServiceConfig.getServiceMonth();
        // 获取用户id
        Long userId = userPaidRecordVo.getUserId();
        // 1. 查询用户的vip信息
        UserInfo userInfo = userInfoMapper.selectOne(
                new LambdaQueryWrapper<UserInfo>()
                        .eq(UserInfo::getId, userId)
        );
        // 根据用户id查询 用户的vip信息
        // 1. 不是vip 或者vip过期直接新增
        if (!getUserVipStatus(userInfo).equals(1)) {
            UserVipService userVipService = new UserVipService();
            userVipService.setUserId(userId);
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipService.setStartTime(new Date());
            // 计算到期时间
            DateTime expireTime = new DateTime().plusMonths(serviceMonth);
            userVipService.setExpireTime(expireTime.toDate());
            // 保存
            userVipServiceMapper.insert(userVipService);
            // 更新用户信息
            userInfo.setIsVip(1);
            userInfo.setVipExpireTime(expireTime.toDate());
            userInfoMapper.updateById(userInfo);
        }else {
            // 查询用户的vip过期时间
            Date oldVipExpireTime = userInfo.getVipExpireTime();
            // 更新用户的vip过期时间
            Date newVipExpireTime = new DateTime(oldVipExpireTime).plusMonths(serviceMonth).toDate();
            UserVipService userVipService = new UserVipService();
            userVipService.setUserId(userId);
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipService.setStartTime(oldVipExpireTime);
            userVipService.setExpireTime(newVipExpireTime);
            userVipServiceMapper.insert(userVipService);
            // 更新userInfo
            userInfo.setVipExpireTime(newVipExpireTime);
            userInfoMapper.updateById(userInfo);
        }
    }

    // 2. 提交的是专辑
    private void saveAlbum(UserPaidRecordVo userPaidRecordVo) {
        UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
        userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
        userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
        userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
        userPaidAlbumMapper.insert(userPaidAlbum);
    }

    // 3. 提交的是声音
    private void saveTracks(UserPaidRecordVo userPaidRecordVo) {
        // 需要专辑的id 可以查询声音的信息  也可以查询专辑的信息(通过声音信息的albumId)
        List<Long> itemIdList = userPaidRecordVo.getItemIdList();
        // 远程调用获取专辑Id
        Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfoInner(itemIdList.get(0));
        AssertUtil.resultAssert(trackInfoResult, ResultCodeEnum.DATA_ERROR);
        TrackInfo trackInfo = trackInfoResult.getData();
        Long albumId = trackInfo.getAlbumId();
        for (Long trackId : itemIdList) {
            UserPaidTrack userPaidTrack = new UserPaidTrack();
            userPaidTrack.setUserId(userPaidRecordVo.getUserId());
            userPaidTrack.setTrackId(trackId);
            userPaidTrack.setAlbumId(albumId);
            userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
            userPaidTrackMapper.insert(userPaidTrack);
        }
    }

    // 查询用户的vip信息 返回 Integer
    // 1 是 vip
    // -1 vip 过期
    // 0 不是vip
    private Integer getUserVipStatus(UserInfo userInfo) {

        if (userInfo == null) {
            throw new GuiguException("用户信息异常");
        }
        // 是有效vip
        if (userInfo.getIsVip() == 1 && userInfo.getVipExpireTime().after(new Date())) {
            return 1;
            // vip过期
        } else if (userInfo.getIsVip() == 1 && userInfo.getVipExpireTime().before(new Date())) {
            return -1;
        } else {
            // 不是vip
            return 0;
        }

    }

}
